<?php

namespace app\services;

use app\models\UserAddress;
use app\models\UserAnswerRecords;
use app\models\UserCreditRecords;
use app\models\UserDonateRecords;
use app\models\UserDonateRecordsDetail;
use app\models\Users;
use app\models\UserTokens;
use app\models\Wxprograms;
use GuzzleHttp\Client;

class UserService extends ServiceBase
{
    /**
     * @param $id
     * @return Users|array|mixed|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserById($id)
    {
        $user = Users::find($id);

        if($user instanceof Users){
            return $user;
        }
        return [];
    }

    public function getUserByAccount($account){
        $user = Users::where("account",$account)->find();
        return $user;
    }

    public function getLists($params=[], $page=1, $pagesize=10)
    {
        return Users::lists($params,$page,$pagesize);
    }

    public function check($account)
    {
        $user = Users::where('account',$account)->where("status",1)->find();
        if($user instanceof Users)
        {
            return $user;
        }else{
            return [];
        }
    }

    public function makeToken($userId)
    {
        $ttl = 86400 * 7;
        $token = UserTokens::where(['userId' => $userId, 'status' => UserTokens::STATUS_NORMAL])
            ->find();

        if (!$token) {
            $token = new UserTokens();
            $token->userId = $userId;
            $token->token = (new UtilService())->uuid();
            $token->status = UserTokens::STATUS_NORMAL;
            $token->save();
        }

        return $token;
    }

    /**
     * @param $token
     * @return Users|array|mixed|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function checkToken($token)
    {
        $userToken = UserTokens::where(['token' => $token])->find();
        if (!$userToken) {
            return null;
        }

        return $this->getUserById($userToken->userId);
    }

    /**
     * @param $token
     * @return bool
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function expiryToken($token)
    {
        $token = UserTokens::where(['token' => $token])->find();
        $token->status = UserTokens::STATUS_VAILD;
        $token->save();
        return true;
    }

    /**
     * 获取用户地址
     * @param array $params
     * @param int $page
     * @param int $pagesize
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getAddressLists($params=[], $page=1, $pagesize=10)
    {
        $lists = UserAddress::lists($params, $page, $pagesize);

        return $lists;
    }

    /**
     * @param array $params
     * @param int $page
     * @param int $pagesize
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getDonateLists($params=[], $page=1, $pagesize=10)
    {
        $lists = UserDonateRecordsDetail::lists($params, $page, $pagesize);

        return $lists;
    }

    /**
     * @param array $params
     * @param int $page
     * @param int $pagesize
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getCreditLists($params=[], $page=1, $pagesize=10)
    {
        $lists = UserCreditRecords::lists($params, $page, $pagesize);

        return $lists;
    }

    /**
     * @param array $params
     * @param int $page
     * @param int $pagesize
     * @return \think\Paginator
     * @throws \think\db\exception\DbException
     */
    public function getAnswerLists($params=[], $page=1, $pagesize=10)
    {
        $lists = UserAnswerRecords::lists($params, $page, $pagesize);

        return $lists;
    }

    /**
     * @param $appletId
     * @param $code
     * @return mixed
     * @throws \Exception
     */
    public function getWxInfo($appletId, $code)
    {
        try{
            $wxprogram = Wxprograms::find($appletId);

            $appId = $wxprogram->appId;
            $secret = $wxprogram->appSecret;
            $url = "https://api.weixin.qq.com/sns/jscode2session?appid=".$appId."&secret=".$secret."&js_code=".$code."&grant_type=authorization_code";

            $client = new Client();
            $res = $client->get($url);

            $data = json_decode($res->getBody());

            if(isset($data->errcode) && $data->errcode != 0){
                throw new \Exception($data->errmsg);
            }

            return $data;

        }catch(\Exception $e){
            throw new \Exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 用openid获取用户信息
     * @param $openid
     * @return Users|array|mixed|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getUserByOpenid($openid)
    {
        $user = Users::where(['openid' => $openid])->find();

        if ($user instanceof Users) {
            return $user;
        } else {
            return [];
        }
    }

    /**
     * @param Users $user
     * @param $sessionKey
     */
    public function saveSessionKey(Users $user, $sessionKey)
    {
        $user->sessionKey = $sessionKey;
        $user->save();
    }

    public function addUser($params)
    {
        try {
            $user = Users::where(['openid' => $params['openid']])->find();
            if (!$user) {
                $user = new Users();
                foreach ($params as $key => $val) {
                    $user->$key = $val;
                }
                $user->save();

                $this->createUniCode($user);
            }

            return $user;

        } catch (\Exception $e) {
            throw new \Exception($e->getMessage(), $e->getCode());
        }
    }

    public function createUniCode(Users $user)
    {
        if (mb_strlen($user->uniCode) != 10) {
            $uniCode = substr(uniqid('', true), 16).substr(microtime(), 2, 3);

            $user->uniCode = $uniCode;
            $user->save();
        }
    }

    public function update(Users $user, $params)
    {
        if (!empty($params)) {
            foreach ($params as $key => $val) {
                $user->$key = $val;
            }

            $user->save();
        }
    }

    public function export($select)
    {
        $title = '用户数据'.date('YmdHis');

        $users = Users::where($select['where'])
            ->order($select['order'])
            ->select();

        $objPHPExcel = new \PHPExcel();
        $objWriter = new \PHPExcel_Writer_Excel2007($objPHPExcel); //设置保存版本格式

        $objPHPExcel->getActiveSheet()->setCellValue('A1', 'ID');
        $objPHPExcel->getActiveSheet()->setCellValue('B1', '微信名');
        $objPHPExcel->getActiveSheet()->setCellValue('C1', '真实姓名');
        $objPHPExcel->getActiveSheet()->setCellValue('D1', '用户唯一码');
        $objPHPExcel->getActiveSheet()->setCellValue('E1', '性别');
        $objPHPExcel->getActiveSheet()->setCellValue('F1', '联系电话');
        $objPHPExcel->getActiveSheet()->setCellValue('G1', '总爱心值');
        $objPHPExcel->getActiveSheet()->setCellValue('H1', '荣誉值');
        $objPHPExcel->getActiveSheet()->setCellValue('I1', '已助力值');
        $objPHPExcel->getActiveSheet()->setCellValue('J1', '院校');
        $objPHPExcel->getActiveSheet()->setCellValue('K1', '院系');
        $objPHPExcel->getActiveSheet()->setCellValue('L1', '入学年份');
        $objPHPExcel->getActiveSheet()->setCellValue('M1', '创建时间');

        foreach ($users as $key => $user) {
            $i = $key + 2;
            $objPHPExcel->getActiveSheet()->setCellValue('A' . $i, $user->userId,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('B' . $i, $user->userName,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('C' . $i, $user->realName,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('D' . $i, $user->uniCode,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('E' . $i, $user->getGenderText(),\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('F' . $i, $user->phone,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('G' . $i, $user->totalCredit,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('H' . $i, $user->currentCredit,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('I' . $i, $user->donateCredit,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('J' . $i, $user->university()->value('universityName'),\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('K' . $i, $user->major,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('L' . $i, $user->year,\PHPExcel_Cell_DataType::TYPE_STRING);
            $objPHPExcel->getActiveSheet()->setCellValue('M' . $i, $user->createdAt,\PHPExcel_Cell_DataType::TYPE_STRING);
        }

        header("Content-Type:application/force-download");
        header("Content-Type:application/vnd.ms-execl");
        header("Content-Type:application/octet-stream");
        header("Content-Type:application/download");;
        header('Content-Disposition:attachment;filename='.$title.'.xlsx');
        header("Content-Transfer-Encoding:binary");
//        $objWriter->save($title.'.xls');
        $objWriter->save('php://output');
    }
}